package main

import (
	"context"
	"fmt"
	"log"
	"net"
	"net/http"

	logger "websocket-server/log" // 导入日志模块，使用别名避免冲突
	"websocket-server/ws"         // 使用模块路径导入ws包

	"github.com/gin-gonic/gin"
	"go.uber.org/fx"
)

const (
	// 服务器端口
	ServerPort = ":9000"
)

// Server 服务器结构体
type Server struct {
	hub  *ws.Hub
	gin  *gin.Engine
	port string
}

// NewServer 创建新的服务器实例
func NewServer(hub *ws.Hub) *Server {
	gin.SetMode(gin.ReleaseMode)
	r := gin.New()
	r.Use(gin.Logger())
	r.Use(gin.Recovery())

	server := &Server{
		hub:  hub,
		gin:  r,
		port: ServerPort,
	}

	// 设置路由
	server.setupRoutes()

	return server
}

// setupRoutes 设置路由
func (s *Server) setupRoutes() {
	// WebSocket路由
	s.gin.GET("/", s.handleWebSocket)
	// 状态查询接口
	s.gin.GET("/status", s.handleStatus)
	// 静态文件服务
	s.gin.Static("/static", "./static")
}

// Start 启动服务器
func (s *Server) Start(lifecycle fx.Lifecycle) {
	lifecycle.Append(fx.Hook{
		OnStart: func(context.Context) error {
			log.Printf("多用户WebSocket服务器启动在端口 %s", s.port)
			log.Printf("管理接口: http://localhost%s/status", s.port)

			go func() {
				if err := s.gin.Run(s.port); err != nil && err != http.ErrServerClosed {
					log.Fatal("服务器启动失败:", err)
				}
			}()
			return nil
		},
		OnStop: func(context.Context) error {
			log.Println("服务器正在关闭...")
			return nil
		},
	})
}

// handleWebSocket WebSocket处理函数
func (s *Server) handleWebSocket(c *gin.Context) {
	conn, err := ws.Upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Printf("WebSocket升级失败: %v", err)
		return
	}

	// 生成会话ID
	s.hub.Mutex.Lock()
	s.hub.Counter++
	sessionID := fmt.Sprintf("session_%d", s.hub.Counter)
	s.hub.Mutex.Unlock()

	// 创建用户会话
	session := ws.NewUserSession(conn, sessionID, s.hub)

	// 启动读写协程（不立即注册，等收到start消息后再注册）
	go session.WritePump()
	go session.ReadPump()
}

// handleStatus 状态查询接口
func (s *Server) handleStatus(c *gin.Context) {
	status := s.hub.GetSessionsStatus()
	c.JSON(http.StatusOK, status)
}

// getLocalIP 获取本机IP地址
func getLocalIP() string {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return "localhost"
	}

	for _, addr := range addrs {
		if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				return ipnet.IP.String()
			}
		}
	}
	return "localhost"
}

// main 主函数
func main() {
	// 初始化日志系统
	logWriter, err := logger.InitLogging()
	if err != nil {
		log.Fatal("初始化日志系统失败:", err)
	}
	defer logWriter.Close()

	app := fx.New(
		// 提供依赖
		fx.Provide(
			ws.NewHub,
			NewServer,
		),
		// 启动服务器生命周期管理
		fx.Invoke(func(server *Server) {
			// 启动Hub
			go server.hub.Run()
		}),
		// 启动服务器
		fx.Invoke(func(server *Server) {
			// 直接启动服务器，不使用fx生命周期
			go func() {
				log.Printf("多用户WebSocket服务器启动在端口 %s", server.port)
				// 获取本机IP地址
				localIP := getLocalIP()
				log.Printf("管理接口: http://%s%s/status", localIP, server.port)

				if err := server.gin.Run(server.port); err != nil && err != http.ErrServerClosed {
					log.Fatal("服务器启动失败:", err)
				}
			}()
		}),
	)

	app.Run()
}
